﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConciseMarkupLanguage.Utils
{
    public static class Extensions
    {
        public static bool ContainsKey<T>(this IList<T> list, int key)
        {
            return list.Count > key;
        }

        public static TDict Merge<TDict, TKey, TVal>(this TDict dict, params IDictionary<TKey, TVal>[] others) where TDict : IDictionary<TKey, TVal>
        {
            foreach (var d in others.Where(d => d != null))
                foreach (var p in d)
                    dict[p.Key] = p.Value;
            return dict;
        }

        public static TRet Aggregate<TRet, TVal>(this IEnumerable<TVal> e, Func<TVal, TRet> seed, Func<TRet, TVal, TRet> func)
        {
            return e.Skip(1).Aggregate(seed(e.First()), func);
        }

        public static IEnumerable<T> DeepCopy<T>(this IEnumerable<T> collection) where T : ICloneable
        {
            return collection.Select(x => (T)x.Clone());
        }

        public static Dictionary<string, object> ToDictionary(this object obj)
        {
            if (obj == null)
                return new Dictionary<string, object>(0);
            if (obj is Dictionary<string, object>)
                return (Dictionary<string, object>)obj;
            if (obj is IEnumerable<KeyValuePair<string, object>>)
                return ((IEnumerable<KeyValuePair<string, object>>)obj).ToDictionary(x => x.Key, x => x.Value);
            return obj.GetType().GetProperties().Where(x => x.CanRead)
                .ToDictionary(x => x.Name, x => x.GetValue(obj, null));
        }

        public static IEnumerable<KeyValuePair<int, T>> Enumerate<T>(this IEnumerable<T> enumerable)
        {
            int i = 0;
            return enumerable.Select(e => new KeyValuePair<int, T>(i++, e));
        }
    }
}
